package com.whucke.im.client;

import com.whucke.im.cache.Cache;
import com.whucke.im.handler.MessageChannelHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


/**
 * netty 客户端
 *
 * @author Zhang Peng
 * @since 2019/2/23 19:56
 */
@Component
public class Client implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(Client.class);
    @Value("${netty.server.host}")
    private String host;
    @Value("${netty.server.port}")
    private int port;

    @Override
    public void run() {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new HttpClientCodec());//客户端编解码使用
                            ch.pipeline().addLast(new HttpObjectAggregator(65536)); //把多个消息转换成一个FullHttpRequest或者FullHttpResponse
                            ch.pipeline().addLast(new ChunkedWriteHandler()); //支持异步发送大码流数据请求，方便文件传输
                            ch.pipeline().addLast(new MessageChannelHandler());
                        }
                    });
            ChannelFuture future = bootstrap.connect(host, port).sync();
            future.addListener(f -> {
                if (f.isSuccess()) {
                    logger.info("连接服务器[{}:{}]成功!", host, port);
                    //缓存连接信息
                    Cache.socketChannel = (SocketChannel) future.channel();
                }
            });
            future.channel().closeFuture().addListener(f -> {
                //断开服务器连接
                if (f.isDone()) {
                    logger.info("断开服务器连接");
                }
            }).sync();
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("连接服务器[{}:{}]成功!", host, port);
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

}
